package com.tuo51.evaluate.service.impl;


import com.tuo51.evaluate.domain.evaluatingV2.EvaluateV2Dimension;
import com.tuo51.evaluate.domain.evaluatingV2.EvaluateV2Item;
import com.tuo51.evaluate.domain.evaluatingV2.EvaluateV2Question;
import com.tuo51.evaluate.domain.evaluatingV2.EvaluateV2Tool;
import com.tuo51.evaluate.domain.tags.RelObjectTag;
import com.tuo51.evaluate.repositories.evaluatev2.EvaluateV2DimensionRepository;
import com.tuo51.evaluate.repositories.evaluatev2.EvaluateV2ItemRepository;
import com.tuo51.evaluate.repositories.evaluatev2.EvaluateV2QuestionRepository;
import com.tuo51.evaluate.repositories.evaluatev2.EvaluateV2ToolRepository;
import com.tuo51.evaluate.service.ImportService;
import com.tuo51.evaluate.service.tag.TagService;
import com.tuo51.foudation.exception.BusinessException;
import com.tuo51.foudation.model.ErrorCode;
import com.tuo51.foudation.model.MemVerificationCache;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.Transient;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class ImportServiceImpl implements ImportService {

    @Autowired
    private MemVerificationCache cache;

    @Autowired
    private EvaluateV2QuestionRepository questionRepository;

    @Autowired
    private EvaluateV2DimensionRepository dimensionRepository;

    @Autowired
    private EvaluateV2ItemRepository itemRepository;

    @Autowired
    private EvaluateV2ToolRepository toolRepository;

    @Autowired
    private TagService tagService;

    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Boolean importQuestion(MultipartFile file) {
        if (file==null) {
            throw  new BusinessException("12345", "file 不能为空");
        }

        //清除掉问题计数器
        List<EvaluateV2Item> items = itemRepository.findAll();
        for (EvaluateV2Item item : items){
            item.setQuestionCount(0);
        }
        itemRepository.saveAll(items);

        //缓存维度
        List<EvaluateV2Dimension> dimensions = dimensionRepository.findAllByDeletedOrderByCode(false);

        HashMap<String, EvaluateV2Dimension> mapping = new HashMap<>();

        dimensions.stream().forEach( p -> {
            mapping.put(p.getName(), p);
        });

        try {
            XSSFWorkbook workbook = new XSSFWorkbook(file.getInputStream());

            //有多少个sheet
            int sheets = workbook.getNumberOfSheets();
            for (int i = 0; i < sheets; i++) {
                XSSFSheet sheet = workbook.getSheetAt(i);
                //获取多少行
                int rows = sheet.getPhysicalNumberOfRows();

                //遍历每一行，注意：第 0 行为标题
                for (int j = 1; j < rows; j++) {
                    //获得第 j 行
                    XSSFRow row = sheet.getRow(j);

                    //序号	题目	准备用具	测评维度	适用月龄
                    int paperIndex = (int)row.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getNumericCellValue();
                    String questionTitle = row.getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
                    String parentAnswer = row.getCell(2, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
                    String toolName = row.getCell(3, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
                    String dimensionName = row.getCell(4, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
                    int month = (int)row.getCell(5, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getNumericCellValue();

                    String operationGuide = row.getCell(6, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
                    String passingCriteria = row.getCell(7, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();

                    String monthStr = month + "";
                    EvaluateV2Dimension dimension = mapping.get(dimensionName.trim());

                    System.out.println(String.format("processing\n %s, %s, %s, %s, %s", paperIndex, questionTitle, toolName, dimensionName, monthStr));

                    if(dimension == null){
                        System.err.println(String.format("import [P] failed\n %s, %s, %s, %s, %s", paperIndex, questionTitle, toolName, dimensionName, monthStr));
                        continue;
                    }

                    EvaluateV2Item baseItem = itemRepository.findTopByDimensionIdAndMonth(dimension.getId(), month);
                    if(baseItem == null){
                        System.err.println(String.format("base item not found"));

                        baseItem = new EvaluateV2Item();
                        baseItem.setDimensionId(dimension.getId());
                        baseItem.setDimensionName(dimensionName);
                        baseItem.setMonth(month);

                        //找到上個baseItem
                        List<EvaluateV2Item> top2 = itemRepository.findTop2ByDimensionIdAndMonthLessThanAndDeletedOrderByMonthDesc(dimension.getId(), month, false);
                        if(top2 == null || top2.size() == 0){
                            baseItem.setScore(month);
                        }else{
                            EvaluateV2Item prevItem = top2.get(0);
                            baseItem.setScore(month - prevItem.getMonth());
                        }
                        itemRepository.save(baseItem);
                    }

                    List<EvaluateV2Question> questions = questionRepository.findAllByItemIdAndDeletedIsFalseOrderByIndexOnPaper(baseItem.getId());
                    if(questions != null && questions.size() > 0){
                        questionRepository.deleteAll(questions);
                    }

                    EvaluateV2Question question = new EvaluateV2Question();
                    question.setIndexOnPaper(paperIndex);
                    question.setItem(baseItem);

                    question.setMonth(month);
                    question.setParentAnswer(StringUtils.isNotBlank(parentAnswer));
                    question.setTitle(questionTitle);

                    question.setOperationGuide(operationGuide);
                    question.setPassingCriteria(passingCriteria);

                    questionRepository.save(question);

                    baseItem.setQuestionCount(baseItem.getQuestionCount()+1);

                    String[] tt = toolName.split("、");
                    for(String t : tt){
                        if(StringUtils.isBlank(t)){
                            continue;
                        }


                        EvaluateV2Tool tool = new EvaluateV2Tool();
                        tool.setQuestion(question);
                        tool.setImgUrl(String.format("https://oss.tuo51.com/public/evaluate_v2_tools/%s.jpg",URLEncoder.encode( t, "UTF-8")));

                        String[] comps = t.split("x");
                        if(comps.length == 1){  //always lager than 1
                            tool.setTitle(t);
                            tool.setCount(1);
                            tool.setUnit("个");
                        }else{
                            tool.setTitle(comps[0]);

                            String[] countAndUnit = comps[1].split("(?<=\\d)(?!=(\\d))");
                            if(countAndUnit.length == 1){
                                tool.setCount(Integer.parseInt(comps[1]));
                                tool.setUnit("个");
                            }else {
                                tool.setCount(Integer.parseInt(countAndUnit[0]));
                                tool.setUnit(countAndUnit[1]);
                            }
                        }

                        toolRepository.save(tool);
                    }

                }
            }

        } catch (IOException e) {
            throw new BusinessException("12345", "错误");
        }
        return true;
    }


    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Boolean importHighLevelInfo20220426(MultipartFile file){
        if (file==null) {
            throw  new BusinessException("12345", "file 不能为空");
        }

        try {
            XSSFWorkbook workbook = new XSSFWorkbook(file.getInputStream());

            //有多少个sheet
            int sheets = workbook.getNumberOfSheets();

            for (int i = 0; i < sheets; i++) {
                XSSFSheet sheet = workbook.getSheetAt(i);

                System.out.println(String.format("import sheet with name : %s", sheet.getSheetName() ));

                //
//                领域	月龄	能力拓展内容	视频一标题	视频一	视频 二标题	视频二
//                社会性行为	1	"1.寻找乳房或奶瓶
//                目的：通过为宝宝哺乳，促进宝宝对生活环境的适应性。
//                准备：母乳或配方奶粉。
//                方法：喂哺时不要急于将乳头送到宝宝口中，促使寻找形成条件反射。
//                注意：宝宝能熟练含吸乳头后开始，早期尽可能让宝宝早些找到乳头，逐渐延长。
//
//                2.玩腕铃、吃手
//                目的：宝宝手的运动及手、口的感觉发育。
//                准备：可戴在手腕上的小铃。
//                方法：为宝宝戴小腕铃，让宝宝自己玩耍，注视、听声响,要让宝宝吃手。
//                注意：防止赘物脱落及划伤面部、口腔。"	社会性行为_1月龄_寻找乳房或奶瓶	https://tuo51-evaluation.oss-cn-shanghai.aliyuncs.com/manual/video/Act-ss-mp4-ld/社会性行为_1月龄_寻找乳房或奶瓶.mp4	社会性行为_1月龄_吃手	https://tuo51-evaluation.oss-cn-shanghai.aliyuncs.com/manual/video/Act-ss-mp4-ld/社会性行为_1月龄_吃手.mp4

                //获取多少行
                int rows = sheet.getPhysicalNumberOfRows();

                int DIMENSION_COL = 0;
                int MONTH_COL = 0;
                int BRINGUP_COL = 1;
                int GROWTH_LINE = 2;
                int EXTINFO_LINE = 3;

//                //月龄
//                XSSFRow m_row = sheet.getRow(MONTH_LINE);
//                String monthStr = m_row.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
//                Integer month = Integer.parseInt(monthStr.replaceAll("[^\\d]", ""));
//
//                //观察内容
//                XSSFRow o_row = sheet.getRow(DOMAIN_LINE);
//                String observationStr = o_row.getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
//
//                //运动发育
//                XSSFRow g_row = sheet.getRow(GROWTH_LINE);
//                String growth = g_row.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
//
//                //高级信息
//                XSSFRow e_row = sheet.getRow(EXTINFO_LINE);
//                String extra_info = e_row.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
//
//                String[] comps = extra_info.split("(指导方案|培养建议|父母手册)");
//                if(comps != null){
//                    for(int k = 0; k < comps.length; k++){
//                        comps[k] = comps[k].trim();
//                    }
//                }
//
////                log.debug("{} {} {} {}", comps[0], comps[1], comps[2], comps[3]);
//
//                if(comps.length < 4 || StringUtils.isBlank(observationStr) /**|| StringUtils.isBlank(growth) || StringUtils.isBlank(comps[2]) || StringUtils.isBlank(comps[3])*/){
//                    throw  new BusinessException(ErrorCode.ENTITY_MERGE_ERROR, "信息不能为空");
//                }
//
//                EvaluateV2Dimension dimension = dimensionRepository.getByName(dimensionName);
//                if(dimension == null){
//                    throw  new BusinessException(ErrorCode.ENTITY_MERGE_ERROR, "能区不存在");
//                }
//
//                EvaluateV2Item item = itemRepository.findTopByDimensionIdAndMonth(dimension.getId(), month);
//                if(item == null){
//                    throw  new BusinessException(ErrorCode.ENTITY_MERGE_ERROR, "月龄不存在");
//                }
//
//                //处理标题
//                observationStr = observationStr.trim().replaceFirst("^观察内容(：|\\:)", "").trim();
//
//                growth = growth.trim().replaceFirst("^.+发育(\\:|：)","").trim();
//
//                //保存
//                item.setDevelopmentStatus(growth.trim());
//                item.setObservation(observationStr.trim());
//                item.setGuide(comps[1].trim());
//                item.setBringUp(comps[2].trim());
//                item.setParentManual(comps[3].trim());
//
//                itemRepository.save(item);
            }

            System.out.println(String.format("import finished"));

        } catch (IOException e) {
            throw new BusinessException("12345", "错误");
        }
        return true;
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public Boolean importHighLevelInfo(MultipartFile file) {
        if (file==null) {
            throw  new BusinessException("12345", "file 不能为空");
        }

        try {
            XSSFWorkbook workbook = new XSSFWorkbook(file.getInputStream());

            //有多少个sheet
            int sheets = workbook.getNumberOfSheets();

            for (int i = 0; i < sheets; i++) {
                XSSFSheet sheet = workbook.getSheetAt(i);

                System.out.println(String.format("import sheet with name : %s", sheet.getSheetName() ));

                //
                String dimensionName = sheet.getSheetName();

                //获取多少行
                int rows = sheet.getPhysicalNumberOfRows();


                int MONTH_LINE = 0;
                int DOMAIN_LINE = 1;
                int GROWTH_LINE = 2;
                int EXTINFO_LINE = 3;

                //月龄
                XSSFRow m_row = sheet.getRow(MONTH_LINE);
                String monthStr = m_row.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
                Integer month = Integer.parseInt(monthStr.replaceAll("[^\\d]", ""));

                //观察内容
                XSSFRow o_row = sheet.getRow(DOMAIN_LINE);
                String observationStr = o_row.getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();

                //运动发育
                XSSFRow g_row = sheet.getRow(GROWTH_LINE);
                String growth = g_row.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();

                //高级信息
                XSSFRow e_row = sheet.getRow(EXTINFO_LINE);
                String extra_info = e_row.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();

                String[] comps = extra_info.split("(指导方案|培养建议|父母手册)");
                if(comps != null){
                    for(int k = 0; k < comps.length; k++){
                        comps[k] = comps[k].trim();
                    }
                }

//                log.debug("{} {} {} {}", comps[0], comps[1], comps[2], comps[3]);

                if(comps.length < 4 || StringUtils.isBlank(observationStr) /**|| StringUtils.isBlank(growth) || StringUtils.isBlank(comps[2]) || StringUtils.isBlank(comps[3])*/){
                    throw  new BusinessException(ErrorCode.ENTITY_MERGE_ERROR, "信息不能为空");
                }

                EvaluateV2Dimension dimension = dimensionRepository.getByName(dimensionName);
                if(dimension == null){
                    throw  new BusinessException(ErrorCode.ENTITY_MERGE_ERROR, "能区不存在");
                }

                EvaluateV2Item item = itemRepository.findTopByDimensionIdAndMonth(dimension.getId(), month);
                if(item == null){
                    throw  new BusinessException(ErrorCode.ENTITY_MERGE_ERROR, "月龄不存在");
                }

                //处理标题
                observationStr = observationStr.trim().replaceFirst("^观察内容(：|\\:)", "").trim();

                growth = growth.trim().replaceFirst("^.+发育(\\:|：)","").trim();

                //保存
                item.setDevelopmentStatus(growth.trim());
                item.setObservation(observationStr.trim());
                item.setGuide(comps[1].trim());
                item.setBringUp(comps[2].trim());
                item.setParentManual(comps[3].trim());

                itemRepository.save(item);
            }

            System.out.println(String.format("import finished"));

        } catch (IOException e) {
            throw new BusinessException("12345", "错误");
        }
        return true;
    }

    @Transient
    @Transactional(rollbackFor = BusinessException.class)
    public Boolean importQuestionTags(MultipartFile file){
        if (file==null) {
            throw  new BusinessException("12345", "file 不能为空");
        }

        try {
            XSSFWorkbook workbook = new XSSFWorkbook(file.getInputStream());

            //有多少个sheet
            int sheets = workbook.getNumberOfSheets();

            for (int i = 0; i < sheets; i++) {
                XSSFSheet sheet = workbook.getSheetAt(i);

                System.out.println(String.format("import sheet with name : %s", sheet.getSheetName()));

                //获取多少行
                int rows = sheet.getPhysicalNumberOfRows();

                //遍历每一行，注意：第 0 行为标题
                for (int j = 1; j < rows; j++) {
                    //获得第 j 行
                    XSSFRow row = sheet.getRow(j);

                    int paperOnIndex = (int)row.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getNumericCellValue();
                    String title = row.getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
                    String tagStr = row.getCell(2, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();

                    String[] tags = tagStr.split("\\|");

                    EvaluateV2Question q = questionRepository.getByIndexOnPaperAndDeletedIsFalse(paperOnIndex);
                    if (q.getTitle().equals(title.trim())){
                        //创建tag
                        for (String t : tags){
                            if (t.trim().length() == 0){
                                continue;
                            }

                            RelObjectTag relation = tagService.createRelationForQuestion(t, null, q);
                        }
                        //
                    }else{
                        throw new BusinessException(ErrorCode.OBJECT_NOT_MATCH, "问题不匹配");
                    }

                }
            }
        } catch (IOException e) {
            throw new BusinessException("12345", "错误");
        }
        return true;
    }

}
